package com.lzh.file.service.impl;

import com.lzh.file.service.IMinioService;
import io.minio.*;
import io.minio.errors.MinioException;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.exception.ExceptionUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import javax.annotation.PostConstruct;
import javax.annotation.Resource;
import java.io.IOException;
import java.io.InputStream;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;

/**
 * minio服务
 *
 * @author lzh
 */
@Service
@Slf4j
public class MinioServiceImpl implements IMinioService {

    public MinioServiceImpl(MinioClient minioClient) {
        this.minioClient = minioClient;
    }

    @Resource
    private MinioClient minioClient;

    @Value("${minio.bucket}")
    private String bucketName;

    /**
     * 初始化创建Bucket
     */
    @PostConstruct
    public void init() {
        createBucket(bucketName);
    }

    public void createBucket(String bucketName) {
        try {
            boolean found = minioClient.bucketExists(BucketExistsArgs.builder().bucket(bucketName).build());
            if (!found) {
                // 创建存储桶
                minioClient.makeBucket(MakeBucketArgs.builder().bucket(bucketName).build());
                log.info("Bucket created successfully: {}", bucketName);
            } else {
                log.info("Bucket already exists: {}", bucketName);
            }
        } catch (MinioException e) {
            log.error("Error occurred: {}", e);
        } catch (IOException | NoSuchAlgorithmException | InvalidKeyException e) {
            log.error("Error occurred: {}", e);
            throw new RuntimeException(e);
        }
    }

    /**
     * 上传文件到Minio对象存储
     *
     * @param bucketName  桶名字
     * @param objectName  文件名
     * @param stream      流
     * @param size        流大小
     * @param contentType HTTP协议content/type
     */
    public void uploadFile(String bucketName, String objectName, InputStream stream, long size, String contentType) {
        try (InputStream ignored = stream) {
            // 使用MinioClient的putObject方法上传文件
            ObjectWriteResponse objectWriteResponse = minioClient.putObject(PutObjectArgs.builder()
                    .bucket(bucketName) //指定要存储的对象的存储桶（bucket）的名称。
                    .object(objectName) //指定要存储的对象（object）的名称。
                    .stream(stream, size, -1) // 输入流，流大小，缓冲区大小（-1表示读取流的全部内容）
                    .contentType(contentType) //指定了存储的对象的内容类型
                    .build());
            log.debug("minio文件写入成功：{}{}", objectWriteResponse.bucket(), objectWriteResponse.object());
        } catch (Exception e) {
            log.error("minio写入文件异常：{}", ExceptionUtils.getStackTrace(e));
        }
    }
}
